package RPC;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.TimerTask;

import BasicDataType.IPP;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.AmazonSimpleDBClient;
import com.amazonaws.services.simpledb.model.Attribute;
import com.amazonaws.services.simpledb.model.BatchPutAttributesRequest;
import com.amazonaws.services.simpledb.model.CreateDomainRequest;
import com.amazonaws.services.simpledb.model.DeleteAttributesRequest;
import com.amazonaws.services.simpledb.model.DeleteDomainRequest;
import com.amazonaws.services.simpledb.model.Item;
import com.amazonaws.services.simpledb.model.ReplaceableAttribute;
import com.amazonaws.services.simpledb.model.ReplaceableItem;
import com.amazonaws.services.simpledb.model.SelectRequest;

public class SimpleDB extends TimerTask {
	private static String myDomain = "domainName";
	private static AmazonSimpleDB sdb;
	private static String itemName = "Servers";
	private boolean stop = false;

	public SimpleDB() {
		create();
	}

	@Override
	public void run() {
		while (!stop) {
			RPCclient.sessionPing(null);
		}
	}

	public void stop() {
		stop = true;
	}

	public void create() {
		if (sdb != null)
			return;
		BasicAWSCredentials cre = new BasicAWSCredentials("AKIAJTYJZQ7K2OKHSA3A", "I/qMRR3Dk3YvTxp03ZnHrC8dyva5FbpZX7/9LnOo");
		sdb = new AmazonSimpleDBClient(cre);
		if (!containDomain()) {
			try {
				sdb.createDomain(new CreateDomainRequest(myDomain));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		Wait();
	}

	private String get() {
		try {
			String selectExpression = "select * from `" + myDomain + "` where Category = 'Server'";
			SelectRequest selectRequest = new SelectRequest(selectExpression);
			for (Item item : sdb.select(selectRequest).getItems()) {
				for (Attribute attribute : item.getAttributes()) {
					if (attribute.getName().equals("IPP")) {
						// System.out.println("get\n" + attribute.getValue());
						return attribute.getValue();
					}
				}
			}
			return "";
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

	public ArrayList<IPP> getList() {
		ArrayList<IPP> ippList = new ArrayList<IPP>();
		String str = get();
		StringTokenizer st = new StringTokenizer(str, "|");
		try {
			while (st.hasMoreTokens()) {
				ippList.add(new IPP(st.nextToken() + "|" + st.nextToken() + "|"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		Wait();
		return ippList;
	}

	public void update(IPP ipp) {

		ArrayList<IPP> oldList = getList();
		// System.out.println("Contains: " + oldList.contains(ipp));
		if (!ipp.inList(oldList)) {
			String oldString = get();
			try {
				List<ReplaceableItem> IPPLIST = new ArrayList<ReplaceableItem>();
				IPPLIST.add(new ReplaceableItem(itemName).withAttributes(new ReplaceableAttribute("Category", "Server", true), new ReplaceableAttribute("IPP", oldString + ipp.getString(), true)));
				if (get().equals(oldString))
					sdb.batchPutAttributes(new BatchPutAttributesRequest(myDomain, IPPLIST));
				else {
					update(ipp);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		Wait();
	}

	public void delete() {
		try {
			sdb.deleteDomain(new DeleteDomainRequest(myDomain));
		} catch (Exception e) {
			e.printStackTrace();
		}
		Wait();
	}

	public void clear() {
		try {
			sdb.deleteAttributes(new DeleteAttributesRequest(myDomain, itemName));
		} catch (Exception e) {
			e.printStackTrace();
		}
		Wait();
	}

	public static void main(String[] argz) {
		SimpleDB db = new SimpleDB();
		db.update(new IPP("127.0.0.1|79|"));
		// db.clear();
		// db.get();
		db.getList();
		// db.delete();

	}

	private boolean containDomain() {
		try {
			List<String> domainList = sdb.listDomains().getDomainNames();
			return domainList.contains(myDomain);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

	}

	public void Wait() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
